/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package accountmanager;

import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JOptionPane;

/**
 *
 * @author jonesbr
 */
public class BankerFrame extends javax.swing.JFrame {

    DefaultComboBoxModel todcmb;
    DefaultComboBoxModel fromdcmb;
    // declare our money transfer background thread.
    MoneyTransfer moneyTransfer;

    private int depth = 0;

    /**
     * Creates new form BankerFrame
     */
    public BankerFrame() {
        initComponents();

        fromdcmb = new DefaultComboBoxModel();
        todcmb = new DefaultComboBoxModel();
        cboTransferFrom.setModel(fromdcmb);
        cboTransferTo.setModel(todcmb);
        
        // instantiate the MoneyTransfer thread and start it in a new thread.
        moneyTransfer = new MoneyTransfer();
        Thread moneyTransferThread = new Thread(moneyTransfer);
        moneyTransferThread.start();


        IConfigurationManager configurationManager;
        configurationManager = new ConfigurationManager();
        try {
            HashMap<String, String> allConfig = configurationManager.read("config.xml");
            String bankName = allConfig.get("bankname");
            jLabel1.setText(bankName);
        } catch (Exception ex) {
            Logger.getLogger(BankerFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        jPanel1 = new javax.swing.JPanel();
        btnSave = new javax.swing.JButton();
        btnTransfer = new javax.swing.JButton();
        jPanel3 = new javax.swing.JPanel();
        cboTransferFrom = new javax.swing.JComboBox();
        cboTransferTo = new javax.swing.JComboBox();
        txtTransferAmount = new javax.swing.JTextField();
        jPanel2 = new javax.swing.JPanel();
        jLabel2 = new javax.swing.JLabel();
        txtBalance = new javax.swing.JTextField();
        jLabel3 = new javax.swing.JLabel();
        txtRate = new javax.swing.JTextField();
        jLabel4 = new javax.swing.JLabel();
        txtPeriods = new javax.swing.JTextField();
        jLabel5 = new javax.swing.JLabel();
        txtName = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jLabel1.setText("Create Accounts, Transfer Money");
        getContentPane().add(jLabel1, java.awt.BorderLayout.PAGE_START);

        jPanel1.setLayout(new java.awt.BorderLayout());

        btnSave.setText("Save");
        btnSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSaveActionPerformed(evt);
            }
        });
        jPanel1.add(btnSave, java.awt.BorderLayout.WEST);

        btnTransfer.setText("Transfer");
        btnTransfer.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnTransferActionPerformed(evt);
            }
        });
        jPanel1.add(btnTransfer, java.awt.BorderLayout.EAST);

        jPanel3.setLayout(new java.awt.GridLayout(0, 3));

        cboTransferFrom.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        jPanel3.add(cboTransferFrom);

        cboTransferTo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        jPanel3.add(cboTransferTo);

        txtTransferAmount.setMinimumSize(new java.awt.Dimension(80, 20));
        txtTransferAmount.setPreferredSize(new java.awt.Dimension(80, 20));
        jPanel3.add(txtTransferAmount);

        jPanel1.add(jPanel3, java.awt.BorderLayout.CENTER);

        getContentPane().add(jPanel1, java.awt.BorderLayout.PAGE_END);

        jPanel2.setLayout(new java.awt.GridLayout(0, 2));

        jLabel2.setText("Balance");
        jPanel2.add(jLabel2);
        jPanel2.add(txtBalance);

        jLabel3.setText("Rate");
        jPanel2.add(jLabel3);
        jPanel2.add(txtRate);

        jLabel4.setText("Periods");
        jPanel2.add(jLabel4);
        jPanel2.add(txtPeriods);

        jLabel5.setText("Name");
        jPanel2.add(jLabel5);
        jPanel2.add(txtName);

        getContentPane().add(jPanel2, java.awt.BorderLayout.CENTER);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveActionPerformed
        // Create a new Account.
        Account myAccount = new Account();
        // store values in the account.
        String strBalance = txtBalance.getText();
        double dblBalance = parseDouble(strBalance, "You have entered invalid data.  Please try again.");
        myAccount.setBalance(dblBalance);

        String strPeriods = txtPeriods.getText();
        int intPeriods = validateInt(strPeriods, "You have entered invalid data.  Please try again.");
        myAccount.setPeriods(intPeriods);

        String strRate = txtRate.getText();
        double dblRate = parseDouble(strRate, "You have entered invalid data.  Please try again.");
        myAccount.setRate(dblRate);

        String strName = txtName.getText();
        myAccount.setName(strName);

        // add this to the model that supplies the drop down boxes.
        todcmb.addElement(myAccount);
        fromdcmb.addElement(myAccount);

    }//GEN-LAST:event_btnSaveActionPerformed

    /**
     * A uniform way to ensure that we are getting good data.
     * @param input the data we want to convert.
     * @param errorMessage the message to show if the user enters bad data.
     * @return valid, parsed data.
     */
    private double parseDouble(String input, String errorMessage) {
        double returnValue = 0.0;
        
        try {
            returnValue = Double.parseDouble(input);
        } catch (NumberFormatException e) {
            // increment our error counter.
            depth++;
            // if we have tried three or fewer times, recruse.
            if (depth < 4) {
                String nextTry = JOptionPane.showInputDialog(this, errorMessage);
                // recurse.
                returnValue = parseDouble(nextTry, errorMessage);
            } else {
                // assume this is a hacking attempt.  Die.
                JOptionPane.showInputDialog("You fool.  I know your game!");
                System.exit(0);
            }
            
        }
        
        return returnValue;
    }
    
    private void btnTransferActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnTransferActionPerformed
        Account fromAccount = (Account) cboTransferFrom.getSelectedItem();
        Account toAccount = (Account) cboTransferTo.getSelectedItem();
        String strTransferAmount = txtTransferAmount.getText();
        double dblTransferAmount = Double.parseDouble(strTransferAmount);
        
        synchronized(moneyTransfer) {
            // pass the fromAccount, toAccount, and amount to MoneyTransfer.
            moneyTransfer.setFromAccount(fromAccount);
            moneyTransfer.setToAccount(toAccount);
            moneyTransfer.setTransferAmount(dblTransferAmount);

            moneyTransfer.notify();
        }
        /**
         * Make an inner class so that we can implement Runnable, which makes this threadable.
         */
        class FooWriter implements Runnable {

            @Override
            public void run() {
                // TODO add your handling code here:
                for (int i = 0; i < 10; i++) {
                    System.out.println("Foo");
                    try {
                        Thread.sleep(10000);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(BankerFrame.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        }

        // create and start a new thread.
        FooWriter fw = new FooWriter();
        Thread fooThread = new Thread(fw);
        fooThread.start();
        
    }//GEN-LAST:event_btnTransferActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(BankerFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(BankerFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(BankerFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(BankerFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new BankerFrame().setVisible(true);
            }
        });
    }

    private int validateInt(String input, String errorMessage) {

        int returnValue = 0;

        try {
            returnValue = Integer.parseInt(input);
        } catch (NumberFormatException e) {
            String nextTry = JOptionPane.showInputDialog(this, errorMessage);
            validateInt(nextTry, input);
        }

        return returnValue;
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnSave;
    private javax.swing.JButton btnTransfer;
    private javax.swing.JComboBox cboTransferFrom;
    private javax.swing.JComboBox cboTransferTo;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JTextField txtBalance;
    private javax.swing.JTextField txtName;
    private javax.swing.JTextField txtPeriods;
    private javax.swing.JTextField txtRate;
    private javax.swing.JTextField txtTransferAmount;
    // End of variables declaration//GEN-END:variables
}
